#include "mesh.h"


Mesh::~Mesh()
{
    //qDebug() << "~Mesh";
    m_glFuns->glDeleteVertexArrays(1, &VAO);
    m_glFuns->glDeleteBuffers(1, &VBO);
    m_glFuns->glDeleteBuffers(1, &EBO);
}

Mesh::Mesh(QOpenGLFunctions_3_3_Core *glFuns, QVector<QVector3D> vertices, QVector<unsigned int> indices, vector<Texture> textures)
    :m_glFuns(glFuns)
{
    this->vertices = vertices;
    this->indices = indices;
    //this->textures = textures;

    //setupMesh();

    //创建VBO和VAO对象，并赋予ID
    m_glFuns->glGenVertexArrays(1, &VAO);
    m_glFuns->glGenBuffers(1, &VBO);
    m_glFuns->glGenBuffers(1,&EBO);
    //绑定VBO和VAO对象
    m_glFuns->glBindVertexArray(VAO);
    m_glFuns->glBindBuffer(GL_ARRAY_BUFFER, VBO);
    //为当前绑定到target的缓冲区对象创建一个新的数据存储。
    //如果data不是NULL，则使用来自此指针的数据初始化数据存储
    m_glFuns->glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex),
                           &vertices[0], GL_STATIC_DRAW);

    m_glFuns->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    m_glFuns->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                           indices.size() * sizeof(unsigned int),&indices[0], GL_STATIC_DRAW); //告知显卡如何解析缓冲里的属性值
    m_glFuns->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    m_glFuns->glEnableVertexAttribArray(0);
}

void Mesh::setupMesh()
{
    //创建VBO和VAO对象，并赋予ID
    m_glFuns->glGenVertexArrays(1, &VAO);
    m_glFuns->glGenBuffers(1, &VBO);
    m_glFuns->glGenBuffers(1,&EBO);
    //绑定VBO和VAO对象
    m_glFuns->glBindVertexArray(VAO);
    m_glFuns->glBindBuffer(GL_ARRAY_BUFFER, VBO);
    //为当前绑定到target的缓冲区对象创建一个新的数据存储。
    //如果data不是NULL，则使用来自此指针的数据初始化数据存储
    m_glFuns->glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex),
                           &vertices[0], GL_STATIC_DRAW);

    m_glFuns->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    m_glFuns->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                           indices.size() * sizeof(unsigned int),&indices[0], GL_STATIC_DRAW); //告知显卡如何解析缓冲里的属性值
    m_glFuns->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    m_glFuns->glEnableVertexAttribArray(0);
#if 0
    m_glFuns->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
    m_glFuns->glEnableVertexAttribArray(1);
    m_glFuns->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
    m_glFuns->glEnableVertexAttribArray(2);
#endif
}

void Mesh::Draw(Shader &shader)
{
    shader.use();
    m_glFuns->glBindVertexArray(VAO);
    m_glFuns->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
    //m_glFuns->glDrawArrays(GL_TRIANGLES, 0, vertices.size());
    m_glFuns->glBindVertexArray(0);
}

Mesh::Mesh(QOpenGLFunctions_3_3_Core *funcs, QVector<QVector3D> s_vertices, QVector<unsigned int> s_indices)
            :m_glFuns(funcs)
{
    this->vertices = s_vertices;
    this->indices = s_indices;

    //创建VBO和VAO对象，并赋予ID
    m_glFuns->glGenVertexArrays(1, &VAO);
    m_glFuns->glGenBuffers(1, &VBO);
    m_glFuns->glGenBuffers(1,&EBO);
    //绑定VBO和VAO对象
    m_glFuns->glBindVertexArray(VAO);
    m_glFuns->glBindBuffer(GL_ARRAY_BUFFER, VBO);

    // 为顶点数据分配内存
    m_glFuns->glBufferData(GL_ARRAY_BUFFER, s_vertices.size() * sizeof(QVector3D), s_vertices.constData(), GL_STATIC_DRAW);

    // 绑定 EBO 对象并分配内存
    m_glFuns->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    m_glFuns->glBufferData(GL_ELEMENT_ARRAY_BUFFER, s_indices.size() * sizeof(unsigned int), s_indices.constData(), GL_STATIC_DRAW);


    // 设置顶点位置属性
    m_glFuns->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(QVector3D), nullptr);
    m_glFuns->glEnableVertexAttribArray(0);


#if 0
    // 为法线数据分配内存
    m_glFuns->glBufferData(GL_ARRAY_BUFFER, s_normals.size() * sizeof(QVector3D), s_normals.constData(), GL_STATIC_DRAW);

    // 设置法线属性
    m_glFuns->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(QVector3D), nullptr);
    m_glFuns->glEnableVertexAttribArray(1);

    // 为纹理坐标数据分配内存
    m_glFuns->glBufferData(GL_ARRAY_BUFFER, s_texcoords.size() * sizeof(QVector2D), s_texcoords.constData(), GL_STATIC_DRAW);

    // 设置纹理坐标属性
    m_glFuns->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(QVector2D), nullptr);
    m_glFuns->glEnableVertexAttribArray(2);
    // 解绑 VAO
    m_glFuns->glBindVertexArray(0);
#endif




}
